﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Buddy.BehaviorTree;
using Buddy.Common;
using Buddy.Common.Math;
using Buddy.CommonBot;
using Buddy.Navigation;
using Buddy.Swtor;
using Buddy.Swtor.Objects;

using WingIt.Routines;
using WingIt.Routines.Mirrors;

using Action = Buddy.BehaviorTree.Action;


namespace WingIt
{
    /// <summary>
    /// <para>CreateBTPS = Create Behavior Tree for PrioritySelector.</para>
    /// <para>All methods in the CreateBTPS class are designed to create Subehaviors that can be included in a PrioritySelector
    /// to accomplish the stated goal.</para>
    /// </summary>
    [RevisionControlId("$Id: Intent.cs 684 2012-08-08 10:09:07Z Chinajade $")]
    public static partial class CreateBTPS
    {
        /// <summary>
        /// <para>Releases the throttle associated with the TOKENDELEGATE (prior to the throttle duration expiring).</para>
        /// <para>By doing so, the intent associated with TOKENDELEGATE is immediately available for reuse.</para>
        /// </summary>
        /// <param name="tokenDelegate"></param>
        /// <returns><para>a behavior tree Composite for use in a PrioritySelector.</para>
        /// <para>The Composite returns RunStatus.Success to the BT parent if the behavior is in progress.
        /// Otherwise, returns RunStatus.Failure indicating no action was necessary.</para>
        /// </returns>
        /// 16Jul2012-22:57UTC chinajade
        //public static Composite IntentComplete(StringProviderDelegate tokenDelegate)
        //{
        //    Logger.ContractRequires(() => tokenDelegate != null, () => "tokenDelegate != null");

        //    return (new Action(unthrottleIntent => {
        //        NamedThrottle.Remove(IntentTokenPrefix + tokenDelegate(unthrottleIntent));
        //        return (RunStatus.Failure);
        //        }));
        //}

        /// <summary>
        /// <para>Notify user of a behavior's intent by emitting MESSAGEDELEGATE to the log.
        /// The message will not be emitted more frequenlty than once every THROTTLEDURATION.</para>
        /// <para>The intent is uniquely identified by TOKENDELEGATE which is any string of the caller's choosing.</para>
        /// <para>Emitting the message may be further gated by the DOWHEN qualifier.</para>
        /// <para>Notes:<list type="bullet">
        /// <item><description><para> * If THROTTLEDURATION is omitted, 60 seconds will be used.</para></description></item>
        /// <item><description><para> * If DOWHEN is omitted, 'always' is assumed.</para></description></item>
        /// </list></para>
        /// </summary>
        /// <param name="tokenDelegate"></param>
        /// <param name="messageDelegate"></param>
        /// <param name="throttleDuration"></param>
        /// <param name="doWhen"></param>
        /// <returns><para>a behavior tree Composite for use in a PrioritySelector.</para>
        /// <para>The Composite returns RunStatus.Success to the BT parent if the behavior is in progress.
        /// Otherwise, returns RunStatus.Failure indicating no action was necessary.</para>
        /// </returns>
        /// 16Jul2012-22:45UTC chinajade
        //public static Composite IntentNotify(StringProviderDelegate tokenDelegate,
        //                                     StringProviderDelegate messageDelegate,
        //                                     TimeSpan? throttleDuration = null,
        //                                     CanRunDecoratorDelegate doWhen = null)
        //{
        //    Logger.ContractRequires(() => tokenDelegate != null, () => "tokenDelegate != null");
        //    Logger.ContractRequires(() => messageDelegate != null, () => "messageDelegate != null");

        //    doWhen = doWhen ?? (ctx => true);       // Resolve optional agument to something sane
        //    throttleDuration = throttleDuration ?? TimeSpan.FromSeconds(60);

        //    return (new Decorator(whenNotThrottled => doWhen(whenNotThrottled) && NamedThrottle.IsReady(IntentTokenPrefix + tokenDelegate(whenNotThrottled)),
        //        new Action(notifyAndThrottle => {
        //            Logger.Write(messageDelegate(notifyAndThrottle));
        //            NamedThrottle.Used(IntentTokenPrefix + tokenDelegate(notifyAndThrottle), throttleDuration.Value);
        //            }))
        //        );
        //}

        //private static string IntentTokenPrefix = "Intent.";        
    }
}
